﻿/*----------------------------------------------------------------
// Copyright (C) 2014 苏州麦迪斯顿医疗科技股份有限公司
// 文件名：UnityServiceBehaviorAttribute.cs
// 文件功能描述：UnityServiceBehaviorAttribute
// 创建标识：顾伟伟-2014-04-03
----------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.Collections.ObjectModel;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using Microsoft.Practices.Unity.InterceptionExtension;

namespace CPOE.Framework.Injection
{
    /// <summary>
    /// 扩展WCF服务行为和终结点行为，实现服务实例的依赖注入和策略注入
    /// </summary>
    public class UnityServiceBehaviorAttribute : Attribute, IServiceBehavior, IEndpointBehavior
    {
        private IUnityContainer _container = new UnityContainer();

        private string _containerName = string.Empty;

        public UnityServiceBehaviorAttribute(string containerName)
        {
            _containerName = containerName;

            UnityConfigurationSection configuration =
                ConfigurationManager.GetSection(UnityConfigurationSection.SectionName) as UnityConfigurationSection;

            if (configuration != null)
                configuration.Configure(_container, _containerName);

            _container.AddNewExtension<Interception>();
           
        }

        #region IServiceBehavior
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
           
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
             _container.Configure<Interception>().SetInterceptorFor(serviceHostBase.Description.ServiceType, 
                new TransparentProxyInterceptor());
            
            foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
            {
                foreach (EndpointDispatcher endpoint in channelDispatcher.Endpoints)
                {
                    endpoint.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(this._container);
                }
            }
        }

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
           
        }
        #endregion

        #region IEndpointBehavior
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
           
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            _container.Configure<Interception>().SetInterceptorFor(endpointDispatcher.DispatchRuntime.ChannelDispatcher.Host.Description.ServiceType,
               new TransparentProxyInterceptor());

            endpointDispatcher.DispatchRuntime.InstanceProvider = new UnityInstanceProvider(this._container);
        }

        public void Validate(ServiceEndpoint endpoint)
        {
           
        }
        #endregion
    }
}
